如何修復錯誤“str”對像沒有屬性“relative_url” (How to fix error 'str' object has no attribute 'relative_url')


問題描述

如何修復錯誤“str”對像沒有屬性“relative_url” (How to fix error 'str' object has no attribute 'relative_url')

我正在嘗試將一些 wagtail 上下文傳遞到 django 項目的搜索頁面。帖子標題出現,但圖片、描述和其他參數未出現在搜索模板中。如何將這些上下文傳遞給搜索模板?

這是我得到的錯誤

AttributeError at /search/
'str' object has no attribute 'relative_url'
Request Method: GET
Request URL:    http://127.0.0.1:8000/search/?q=hel
Django Version: 3.1.3
Exception Type: AttributeError
Exception Value:    
'str' object has no attribute 'relative_url'
Exception Location: C:\Users\Bree\AppData\Roaming\Python\Python37\site‑packages\wagtail\contrib\routable_page\templatetags\wagtailroutablepage_tags.py, line 25, in routablepageurl
Python Executable:  C:\Program Files\Python37\python.exe
Python Version: 3.7.3

這是search.view.py代碼

p>
from django.shortcuts import render

from wagtail.core.models import Page
from wagtail.search.models import Query

from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from news.models import  NewsPage, NewsCategory

def search(request):
    posts = NewsPage.objects.live().public()
    categories = NewsCategory.objects.all()

    # Search
    search_query = request.GET.get('q', None)
    if search_query:
        search_results = NewsPage.objects.live().search(search_query)

        # Log the query so Wagtail can suggest promoted results
        Query.get(search_query).add_hit()
        reversenews = list(reversed(search_results))
        # Pagination
        paginator = Paginator(reversenews, 16) #show 10 articles per page
        page = request.GET.get('page')
        try:
            search_results = paginator.page(page)
        except PageNotAnInteger:
            search_results = paginator.page(1)
        except EmptyPage:
            search_results = paginator.page(paginator.num_pages)
    else:
        search_results = NewsPage.objects.none()

    # Render template
    return render(request, 'search/search.html', {
        'search_query': search_query,
        'search_results': search_results,
        'recent_posts' : posts,
        'categories' : categories
    })

這是搜索模板search.html

{% extends "news/news_index_page.html" %}

{% load static wagtailcore_tags %} 

{% load wagtailembeds_tags %}

{% load wagtailcore_tags %}

{% load static wagtailuserbar %}

{% load wagtailimages_tags %}
{%load static%}
{% load wagtailcore_tags %}

{% load wagtailroutablepage_tags %}

{% block content %}
<div class="container">
    <div class="row">
        <div class="col‑md‑8">

                <h3>Query Results FOR &nbsp;<b>"{{ search_query }}"</b></h3>
            <div class="post">

                    {% if search_results %}
                    <div class="row">

                        {% for result in search_results %}
                        <div class="col‑md‑6 col‑sm‑6"> 
                                <div class="images">
                                    {% image result.blog_image max‑770x480 as blog_img  %}
                                    <a class="images" href="{% pageurl result %}" title="images"><img  src="{{result.blog_image}}" alt="images"></a>
                                </div>
                                <div class="text">
                                    <h2><a href="{% pageurl result %}" title="title">{{result.title}}</a></h2>
                                    <div class="categories">
                                        {% for cat in result.categories.all%}
                                       <a href="{% routablepageurl news_page 'category_view' cat.slug %}" style="color:white">{{cat.name}}</a>
                                        {%endfor%}
                                        <p class="date"><i class="fa fa‑clock‑o"></i>{{result.date}}</p>
                                    </div>
                                    <p>{{result.description}}</p>
                                    <a href="{% pageurl result %}" title="read more">read more</a>
                                </div>

                        {%endfor%} 
                    </div>
                    {% elif search_query %}
                    <p> No results found</p>
                        <img src="{% static '/images/not_found %}" alt="image">
                    {% endif %}
                </div>

                <!‑‑ Pagination ‑‑>
                    {% if search_results.paginator.num_pages > 1 %}
                    <div class="box center float‑left space‑30">
                        <nav class="pagination">
                            {% if search_results.has_previous %}
                            <a class="control prev" href="?page={{ search_results.previous_page_number }}" title="pre"><i class="fa fa‑long‑arrow‑left"></i>Previous</a>
                            {% endif %}
                            <ul>
                                {% for page_num in search_results.paginator.page_range %}
                                <li class="{% if page_num == search_results.number %} active{% endif %}"><a href="?page={{ page_num }}" title="1">{{ page_num }}</a></li>
                                {% endfor %}
                            </ul>
                            {% if search_results.has_next %}
                            <a class="control next" href="?page={{ search_results.next_page_number }}" title="next">Next<i class="fa fa‑long‑arrow‑right"></i></a>
                            {% endif %}
                        </nav>
                        <!‑‑ End pagination ‑‑>
                    </div>
                    {% endif %}
</div>
</div>

這是models.py

from django.db import models
from django.shortcuts import render
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel, MultiFieldPanel, InlinePanel
from wagtail.snippets.edit_handlers import SnippetChooserPanel
from wagtail.core.fields import StreamField
from wagtail.core.models import Page, Orderable
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.snippets.models import register_snippet
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from wagtail.contrib.routable_page.models import RoutablePageMixin, route
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from wagtailmenus.models import MenuPage

from django import forms
import datetime
from datetime import date

from streams import blocks

# Create your models here.



class NewsPageTag(TaggedItemBase):
    content_object = ParentalKey(
        'NewsPage',
        related_name='tagged_items',
        on_delete=models.CASCADE
    )



class NewsIndexPage(RoutablePageMixin, Page):

    custom_title = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text='Overwrites the default title',
    )

    content_panels = Page.content_panels + [
        FieldPanel("custom_title"),
    ]


    def get_context(self, request, *args, **kwargs):
        """Adding custom stuff to our context."""
        context = super().get_context(request, *args, **kwargs)
        posts = NewsPage.objects.live().public()
        context["recent_posts"] = posts
        context["tech_world"] = NewsPage.objects.live().filter(categories = 2)
        context["digital_creatives"] = NewsPage.objects.live().filter(categories = 10)
        context["exclusives"] = NewsPage.objects.live().filter(categories = 4)
        context["news"] = NewsPage.objects.live().filter(categories = 1)
        context["startups"] = NewsPage.objects.live().filter(categories = 3)
        context['news_page'] = self
        context['parent'] = self.get_parent().specific
        context['categories'] = NewsCategory.objects.all()
        return context



    @route(r"^category/(?P<cat_slug>[‑\w]*)/$", name="category_view")
    def category_view(self, request, cat_slug):

        context = self.get_context(request)

        try:
            category = NewsCategory.objects.all().get(slug=cat_slug)
        except Exception:
            category= None
        if category is None:

            pass
        catPosts = NewsPage.objects.all().filter(categories__in=[category])
        reversenews = list(reversed(catPosts))

        paginator = Paginator(reversenews, 6)
        page = request.GET.get("page")
        try:
            # If the page exists and the ?page=x is an int
            posts = paginator.page(page)
        except PageNotAnInteger:
            # If the ?page=x is not an int; show the first page
            posts = paginator.page(1)
        except EmptyPage:
            posts = paginator.page(paginator.num_pages)


        context["posts"]= posts
        context["category"] = NewsCategory.objects.all().get(slug=cat_slug)

        return render(request, "news/cat_posts.html", context)

class NewsPage(Page):
    """Blog detail page."""


    blog_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=False,
        null=True,
        related_name="+",
        on_delete=models.SET_NULL,
    )
    image_description = models.TextField(max_length=500, blank=True, null=True , default=" ")


    categories = ParentalManyToManyField("news.NewsCategory", blank = True)
    date = models.DateTimeField(verbose_name="Post date", default=datetime.datetime.today)
    tags = ClusterTaggableManager(through=NewsPageTag, blank=True)


    content = StreamField(
        [

            ("full_richtext", blocks.RichtextBlock())

        ],
        null=True,
        blank=False
    )
    description = StreamField(
        [

            ("full_richtext", blocks.RichtextBlock())

        ],
        null=True,
        blank=False
    )

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            InlinePanel("news_authors", label="Author", min_num=1, max_num=4)
        ], heading="Author(s)"),

        MultiFieldPanel([
            FieldPanel("categories", widget = forms.CheckboxSelectMultiple),
            FieldPanel('tags'),
            FieldPanel('date'),
        ]),
        ImageChooserPanel("blog_image"),
        FieldPanel('image_description'),
        StreamFieldPanel("content"),
        StreamFieldPanel("description"),
    ]

    @property
    def news_page(self):
        return self.get_parent().specific

    def get_context(self, request, *args, **kwargs):
        context = super(NewsPage, self).get_context(request, *args, **kwargs)
        posts = NewsPage.objects.live().public()
        context['categories'] = NewsCategory.objects.all()
        context['news_page'] = self.news_page
        context['post'] = self
        context["recent_posts"]= NewsPage.objects.live().public()
        return context 

class NewsAuthor(models.Model):
     name = models.CharField(max_length=100)
     description = models.TextField(max_length=500, blank=False, null=True)
     email = models.URLField(blank=True, null=True)
     image = models.ForeignKey(
         "wagtailimages.Image",
         on_delete=models.SET_NULL,
         null = True,
         blank = False,
         related_name="+"
     )


     panels = [
         MultiFieldPanel([
             FieldPanel("name"),
             FieldPanel("description"),
             ImageChooserPanel("image")
         ], heading="Name & Image"),

         MultiFieldPanel([
             FieldPanel("email")
         ], heading="Links")
     ]

     def __str__(self):
        return self.name



register_snippet(NewsAuthor)

class NewsCategory(models.Model):

    name= models.CharField(max_length=255)
    slug = models.SlugField(
        verbose_name="slug",
        allow_unicode= True,
        unique=True,
        max_length=255,
        help_text="A slug to identify posts by this category"
    )

    panels=[
        FieldPanel("name"),
        FieldPanel("slug")
    ]

    class Meta:
        verbose_name = 'News Category'
        verbose_name_plural = 'News Categories'
        ordering = ['name']
    def __str__(self):
        return self.name


register_snippet(NewsCategory)

這是 urls.py

from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin

from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls

from search import views as search_views

urlpatterns = [
    url(r'^django‑admin/', admin.site.urls),

    url(r'^admin/', include(wagtailadmin_urls)),
    url(r'^documents/', include(wagtaildocs_urls)),

    url(r'^search/$', search_views.search, name='search'),

]

我做錯了什麼?


參考解法

方法 1:

It seems like the news_page variable in your template is a string, rather than a page object, as that's the only use of the {% routablepageurl %} tag in the code examples you have shared. However, you don't show where news_page is defined, so I may be mistaken.

I have now looked at your models file, and where you define news_page. You have defined news_page in the context of NewsIndexPage. This will be used when displaying a NewsIndexPage, using Wagtail's internal views, but this is not used when rendering the search view.

Here's the response context you are setting in your search/views.py:

    # Render template
    return render(request, 'search/search.html', {
        'search_query': search_query,
        'search_results': search_results,
        'recent_posts' : posts,
        'categories' : categories
    })

Can you add news_page to the context there?

(by Al4321nimasmi)

參考文件

  1. How to fix error 'str' object has no attribute 'relative_url' (CC BY‑SA 2.5/3.0/4.0)

#wagtail #Python #wagtail-search #django-views #Django






相關問題

Wagtail Cms 是否支持 Google 登錄和用戶登錄添加會話 (Does Wagtail Cms support Google login and user login add session to)

Wagtail Django-form編輯現有對象 (Wagtail Django-form edit existing object)

如何將 Wagtail 'admin' 菜單添加到自定義模板? (How to add Wagtail 'admin' menu to custom templates?)

django.db.utils.OperationalError:外鍵不匹配 - “project_projectpage”引用“auth_user” (django.db.utils.OperationalError: foreign key mismatch - "project_projectpage" referencing "auth_user")

如何使用 Wagtail 鉤子在 Wagtail 中生成自定義鏈接 (How to generate a custom link in Wagtail using Wagtail hooks)

Wagtail:如何設置單元測試以進行簡單的頁面編輯? (Wagtail: How to setup up unittest for simple page edit?)

如何修復錯誤“str”對像沒有屬性“relative_url” (How to fix error 'str' object has no attribute 'relative_url')

如何將帖子從 Wordpress 導入 Wagtail 2(Draftail 編輯器),包括圖像? (How to import posts from Wordpress to Wagtail 2 (Draftail editor) including images?)

如何用外鍵鏈接兩種形式(wagtail 形式和 django 形式)? (How to link two forms (wagtail form and django form) with a foreign key?)

為什麼 RichText 不能在 wagtail 管理員中為帖子工作?這是發生的事情的類型:<h2>嘗試 post.content|richtext</h2> (Why is RichText not working in wagtail admin for posts? This is the type of thing that happens: <h2>Trying post.content|richtext</h2>)

Windows 10 上 wagtail 的客戶端文件夾在哪裡 (Where is the client folder of wagtail on windows 10)

過濾從 Wagtail 核心頁面導入的多個模型的自定義字段 (Filter on custom field across multiple models that import from Wagtail core Page)







留言討論